﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CapaPresentacion.Commands;
using CapaPresentacion.Vistas;
using Entidades;
using CapaLogica;
using System.Windows.Input;
using System.Windows;
using System.Windows.Data;
using System.Transactions;

namespace CapaPresentacion.Controles
{
    class NuevoGastoViewModel
    {

       public event ReiniciarCU ReiniciarCU;

        #region Variables

        private Gasto gasto;
        private Gasto gastoSinModificaciones;

        private string mesGasto;
        private string añoGasto;
        private string importeGasto;

        private RelayCommand saveCommand;
        private RelayCommand newCommand;
        private RelayCommand openCommand;

        #endregion

        #region Propiedades

        public ICommand SaveCommand
        {
            get
            {
                return saveCommand;
            }
        }

        public ICommand OpenCommand
        {
            get
            {
                return openCommand;
            }
        }

        public ICommand NewCommand
        {
            get
            {
                return newCommand;
            }
        }

        public Gasto Gasto
        {
            get { return gasto; }
            set { gasto = value; }
        }

        public string MesGasto
        {
            get { return mesGasto; }
            set { mesGasto = value; }
        }

        public string AñoGasto
        {
            get { return añoGasto; }
            set { añoGasto = value; }
        }

        public string ImporteGasto
        {
            get { return importeGasto; }
            set { importeGasto = value; }
        }

        public List<ViewEntity> ListaMeses { get; set; }
        public List<ViewEntity> ListaCategoriasGastos { get; set; }
        private NuevoGasto view;

        #endregion

        public NuevoGastoViewModel() { }

        public void Inicializar(NuevoGasto vista)
        {

            ListaCategoriasGastos = new CategoriaGastoLogica().ObtenerListaCategorias();

            if (ListaCategoriasGastos.Count > 0)
            {
                this.view = vista;

                this.gasto = new Gasto();
                this.gasto.Eliminado = false;
                this.saveCommand = new RelayCommand(GuardarGasto);
                this.newCommand = new RelayCommand(NuevoGasto);
                this.openCommand = new RelayCommand(AbrirGasto);



                ListaMeses = new List<ViewEntity>();
                ListaMeses.Add(new ViewEntity("Enero"));
                ListaMeses.Add(new ViewEntity("Febrero"));
                ListaMeses.Add(new ViewEntity("Marzo"));
                ListaMeses.Add(new ViewEntity("Abril"));
                ListaMeses.Add(new ViewEntity("Mayo"));
                ListaMeses.Add(new ViewEntity("Junio"));
                ListaMeses.Add(new ViewEntity("Julio"));
                ListaMeses.Add(new ViewEntity("Agosto"));
                ListaMeses.Add(new ViewEntity("Septiembre"));
                ListaMeses.Add(new ViewEntity("Octubre"));
                ListaMeses.Add(new ViewEntity("Noviembre"));
                ListaMeses.Add(new ViewEntity("Diciembre"));

                this.añoGasto = DateTime.Now.Year.ToString();
                this.view.datosNoModificables.Visibility = Visibility.Visible;
                this.view.spDatosGasto.Visibility = Visibility.Collapsed;

            }
            else
            {

                VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "No existen categorías de gastos cargadas en el sistema");
                nueva.ShowDialog();
                this.ReiniciarCU(CasosDeUso.NuevaCategoriaGasto);


            }

        }


        public void Inicializar(NuevoGasto vista, Gasto entidad)
        {
            this.view = vista;
            this.gasto = entidad;
            this.gastoSinModificaciones = (Gasto)entidad.Clone();                      

            this.importeGasto = this.gasto.Importe.ToString();

            this.saveCommand = new RelayCommand(GuardarGasto);
            this.newCommand = new RelayCommand(NuevoGasto);
            this.openCommand = new RelayCommand(AbrirGasto);

            this.view.datosNoModificables.Visibility = Visibility.Collapsed;
            this.view.spDatosGasto.Visibility = Visibility.Visible;
            this.view.lblCategoriagasto.Content = this.gasto.CategoriaGasto.NombreCategoriaGasto;
            this.view.lblPeriodoGasto.Content = this.ObtenerNombreMes(this.gasto.FechaPago.Month) + "/" + this.gasto.FechaPago.Year.ToString();
           
        }

        private void NuevoGasto(Object parameter)
        {
            if (MessageBox.Show("¿Está seguro que desea cargar un nuevo gasto?", "Confirme su Decisión", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                this.ReiniciarCU(CasosDeUso.NuevoGasto);
            }
        }

        private void AbrirGasto(Object parameter)
        {
            if (MessageBox.Show("¿Está seguro que desea editar los datos de un gasto existente?", "Confirme su Decisión", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                this.ReiniciarCU(CasosDeUso.BuscarGasto);
            }
        }

        private void GuardarGasto(Object parameter)
        {
            if (MessageBox.Show("¿Está seguro que desea guardar los datos?", "Confirme su Decisión", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                if (Validaciones())
                {                                     
                    try
                    {
                        if (gasto.IdGasto == Guid.Empty) // Nuevo Proyecto Didáctico
                        {
                            gasto.IdGasto = Guid.NewGuid();
                            gasto.Importe = Convert.ToDecimal(importeGasto);
                            gasto.FechaPago = new DateTime(Convert.ToInt32(this.añoGasto), this.ObtenerNumeroMes(this.mesGasto), 1);


                            new GastoLogica().Agregar(gasto);

                            VentanaAviso nueva = new VentanaAviso(false, "Finalización Exitosa", "El gasto ha sido guardado correctamente");
                            nueva.ShowDialog();

                            this.ReiniciarCU(CasosDeUso.NuevoGasto);

                        }
                        else // Modificación de  Proyecto Didáctico
                        {
                            gasto.Importe = Convert.ToDecimal(importeGasto);                           

                            new GastoLogica().Modificar(gasto);

                            VentanaAviso nueva = new VentanaAviso(false, "Finalización Exitosa", "El gasto ha sido modificado correctamente");
                            nueva.ShowDialog();
                            this.ReiniciarCU(CasosDeUso.NuevoGasto);

                        }

                    }
                    catch (Exception)
                    {

                        VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "  Ha ocurrido un error y el gasto no se ha guardado");
                        nueva.ShowDialog();

                    }
                      
                }
                
            }
        }


        private bool Validaciones()
        {
            if (gasto.IdCategoriaGasto == Guid.Empty)
            {
                if (gastoSinModificaciones != null)
                    this.gasto.IdCategoriaGasto = this.gastoSinModificaciones.IdCategoriaGasto;

                VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "El campo 'Categoría del Gasto' es obligatorio");
                nueva.ShowDialog();
                return false;
            }

            if (this.gasto.IdGasto == Guid.Empty)
            {
                if (String.IsNullOrWhiteSpace(this.mesGasto))
                {
                    VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "El campo 'Mes del Gasto' es obligatorio");
                    nueva.ShowDialog();
                    return false;
                }
            }

            if (this.gasto.IdGasto == Guid.Empty)
            {
                if (String.IsNullOrWhiteSpace(this.añoGasto))
                {
                    VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "El campo 'Año del Gasto' es obligatorio");
                    nueva.ShowDialog();
                    return false;
                }
                else
                {
                    if (this.añoGasto.Length != 4)
                    {
                        VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "El campo 'Año del Gasto' ha sido ingresado de forma incorrecta");
                        nueva.ShowDialog();
                        return false;

                    }


                }
            }

            if (String.IsNullOrWhiteSpace(this.gasto.NumeroTicket))
            {
                if (gastoSinModificaciones != null)
                    this.gasto.NumeroTicket = this.gastoSinModificaciones.NumeroTicket;

                VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "El campo 'Número de Factura/Comprobante/Ticket' es obligatorio");
                nueva.ShowDialog();
                return false;
            }

            if (String.IsNullOrWhiteSpace(this.importeGasto))
            {

                VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "El campo 'Importe del Gasto' es obligatorio");
                nueva.ShowDialog();
                return false;
            }
            else
            {

                if (this.importeGasto == "0")
                {

                    VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "El 'Importe del Gasto' no puede ser cero");
                    nueva.ShowDialog();
                    return false;
                }
                else
                {

                    char[] Importe = this.importeGasto.ToCharArray();
                    int CantComas = 0;
                    for (int i = 0; i < Importe.Length; i++)
                    {
                        if (Importe[i] == ',')
                            CantComas++;
                    }

                    if (CantComas > 1)
                    {

                        VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "El campo 'Importe del Gasto' ha sido ingresado de forma incorrecta");
                        nueva.ShowDialog();
                        return false;

                    }


                }
            }

            if (this.gasto.IdGasto == Guid.Empty) // Nuevo Gasto
            {
                if (new GastoLogica().ExisteGasto(this.gasto.IdCategoriaGasto, this.ObtenerNumeroMes(this.mesGasto), Convert.ToInt32(this.añoGasto)))
                {
                    VentanaAviso nueva = new VentanaAviso(true, "Se ha producido un error", "El gasto ingesado ya existe para el período seleccionado. Elija otra categoría");
                    nueva.ShowDialog();
                    return false;


                }
            }

            return true;

        }

        internal int ObtenerNumeroMes(string mes)
        {

            switch (mes)
            {

                case "Enero":
                    return 1;

                case "Febrero":
                    return 2;

                case "Marzo":
                    return 3;

                case "Abril":
                    return 4;

                case "Mayo":
                    return 5;

                case "Junio":
                    return 6;

                case "Julio":
                    return 7;

                case "Agosto":
                    return 8;

                case "Septiembre":
                    return 9;

                case "Octubre":
                    return 10;

                case "Noviembre":
                    return 11;

                case "Diciembre":
                    return 12;

                default: return 0;

            }

        }

        internal string ObtenerNombreMes(int mes)
        {

            switch (mes)
            {

                case 1:
                    return "Enero";

                case 2:
                    return "Febrero";

                case 3:
                    return "Marzo";

                case 4:
                    return "Abril";

                case 5:
                    return "Mayo";

                case 6:
                    return "Junio";

                case 7:
                    return "Julio";

                case 8:
                    return "Agosto";

                case 9:
                    return "Septiembre";

                case 10:
                    return "Octubre";

                case 11:
                    return "Noviembre";

                case 12:
                    return "Diciembre";

                default: return "Ninguno";

            }

        }


    }
}
